// **************************************************************
// COPYRIGHT(c)2010, xidian University
// All rights reserved.
//
// IP LIB INDEX  :  HiNOC
// IP Name       :  HiNOC
// File name     :  read_ctrl.v
// Module name   :  CPT_CTRL
// Full name     :  CPTURE CONTRL
//
// Author        :  Pan Weitao
// Email         :  panweitao@163.com
// Data          :  2010???10???27???9:54:26
// Version       :  V 1.0
//
// Abstract      :
// Called by     :  
//
// Modification history
// ------------------------------------------------------------------------------------------------------
// //
// $Log$
//
// *********************************************************************

`include    "top_define.v"
// *****************************
//  DEFINE MODULE PORT  //
// ******************************
module CPT_CTRL_NEW(
            //input
            clk                      ,
            rst_n                    ,
            ram_2p_cfg_register,
			 
			      //捕获H口
	          cpt_hm_data_val          ,
            cpt_hm_data              ,
			      hm_cpt_en                ,
			      hm_hm_id                 ,
			      hm_cpt_frame_len         , 
			      //捕获E口
			      cpt_em_data_val          ,
            cpt_em_data              ,
			      em_cpt_en                ,
			      em_hm_id                 ,
			      em_cpt_frame_len         , 

            //rd_info                  ,
            rd_rdy                   ,
            rd_end                   , 			 

		        //2013.8.20 zhangjy
            cpu_rdcpt_en             ,
            cpu_rdcpt_addr           ,
            cpu_rdcpt_data           ,

            cpt_fifo_status          ,

            cpt_busy		             
           );  
		   
// ******************************
// DEFINE PARAMETER
// ******************************
parameter CPT_WIDTH          = 12   ;
parameter CPT_NUM_WIDTH      = 8    ; 
// ******************************
// DEFINE INPUT
// ******************************         
input          clk                  ;
input          rst_n                ;      
input   [9:0]   ram_2p_cfg_register;


input	         cpt_hm_data_val      ;
input  [255:0] cpt_hm_data          ;
input			     hm_cpt_en            ;
input  [7 :0]	 hm_hm_id             ;
input  [10:0]	 hm_cpt_frame_len     ; 
			 
input	         cpt_em_data_val      ;
input  [255:0] cpt_em_data          ;
input			     em_cpt_en            ;
input  [7 :0]	 em_hm_id             ;
input  [10:0]	 em_cpt_frame_len     ; 

input          rd_rdy               ;
input          rd_end               ;
// ******************************
// DEFINE OUTPUT  //
// ******************************      

input                  cpu_rdcpt_en   ;
input  [CPT_WIDTH-1:0] cpu_rdcpt_addr ;
output [31:0]          cpu_rdcpt_data ;

output [31:0]  cpt_fifo_status        ;

output            cpt_busy            ;
// ******************************
// OUTPUT ATRRIBUTE  //
// ******************************
reg             cpt_data_val              ;
reg [255:0]     cpt_data                  ;
wire            cpt_en                    ;
reg [7:0]       cpt_hm_id                 ;
reg [10:0]      cpt_frame_len             ; 

wire            cpt_info_fifo_wren        ;
wire [31:0]     cpt_info_fifo_data        ;
wire            cpt_info_fifo_ren         ;
wire [31:0]     cpt_info_fifo_rdata       ;
wire            cpt_info_fifo_full        ;
wire            cpt_info_fifo_empty       ;
wire [CPT_NUM_WIDTH:0]   cpt_info_fifo_num;
wire [31:0]     cpt_info_fifo_rdata_d1    ;
reg  [31:0]     cpt_info_fifo_rdata_reg   ;
reg  [8:0]      cpt_info_fifo_num_reg     ;
reg             cpt_info_fifo_ren_ff      ;  
// ******************************
// INTERNAL ATRRIBUTE  //
// ******************************                                   

wire rd_end_posff1                  ;
wire [10:0] cpt_rd_frame_len        ;

//2013.8.20 zhangjy

wire cpt_start_en ;
// ******************************
// INSTSNCE MODULE   //
// ******************************

wire [255:0]          cpt_dpram_data;
wire [CPT_WIDTH-1 :0] cpt_dpram_addr;
wire                  cpt_dpram_wren;

assign	cpt_en = hm_cpt_en | em_cpt_en | cpt_hm_data_val | cpt_em_data_val;

always@(*)
begin
	if(cpt_en==1'b1) 
	begin
		if(hm_cpt_en) cpt_hm_id  = hm_hm_id;
		else cpt_hm_id  = em_hm_id;
    end
	else
	   cpt_hm_id =8'd0;
end

always@(*)
begin
	if(cpt_en==1'b1) 
	begin
		if(hm_cpt_en) cpt_frame_len = hm_cpt_frame_len;
		else cpt_frame_len = em_cpt_frame_len;
    end
	else
	   cpt_frame_len = 10'd0;
end

always@(*)
begin
	if(cpt_en==1'b1) 
	begin
		if(hm_cpt_en) cpt_data_val  = cpt_hm_data_val;
		else cpt_data_val  =cpt_em_data_val;
    end
	else
	   cpt_data_val =1'd0;
end

always@(*)
begin
	if(cpt_en==1'b1) 
	begin
		if(hm_cpt_en) cpt_data = cpt_hm_data;
		else cpt_data = cpt_em_data;
    end
	else
	   cpt_data = 256'd0;
end

CPT_WRITE_CTRL_NEW #(.CPT_WIDTH(CPT_WIDTH)) U_CPT_WRITE_CTRL_NEW(
            //input
            .clk                 (clk               ),                      
            .rst_n               (rst_n             ),     
            .cpt_data_val        (cpt_data_val      ),     
            .cpt_data            (cpt_data          ),
            .cpt_en              (cpt_en            ),
            .cpt_frame_len       (cpt_frame_len     ),       
            .hm_id               (cpt_hm_id         ),				 
            //output        
            .dpram_data_i        (cpt_dpram_data    ),     
            .dpram_addr          (cpt_dpram_addr    ),
		        .dpram_wren 	       (cpt_dpram_wren	  ),
		        .cpt_info_fifo_data  (cpt_info_fifo_data),
		        .cpt_info_fifo_wren  (cpt_info_fifo_wren),
            .rd_end              (rd_end_posff1     ),
            .cpt_rd_frame_len    (cpt_rd_frame_len  ),
            .cpt_busy            (cpt_busy          )
             );


CPT_READ_CTRL_NEW U_CPT_READ_CTRL_NEW(
            //input
            .clk                  (clk             ),
            .rst_n                (rst_n           ),
            .rd_rdy               (rd_rdy          ),
            .rd_end               (rd_end          ),	

            //output

            .cpt_info_fifo_empty  (cpt_info_fifo_empty),
            .cpt_info_fifo_ren    (cpt_info_fifo_ren),
            .cpt_info_fifo_rdata  (cpt_info_fifo_rdata[26:16]),

			      .rd_end_posff1      (rd_end_posff1 ),
            .cpt_rd_frame_len   (cpt_rd_frame_len),
			 
			      .cpt_start_en(cpt_start_en)
            );

/*dpram_for_cap U_CPT_MEM0
                            (
                                    .clock(                           clk                      ),
                                    .data(                            cpt_dpram_data           ),
                                    // .address(                         cpt_dpram_addr        ),
                                    .rdaddress(                        cpu_rdcpt_addr          ),
                                    .rden(                            cpu_rdcpt_en             ),
                                    .wraddress(                        cpt_dpram_addr          ),
                                    .wren(                            cpt_dpram_wren           ),
                                    .q(                                cpu_rdcpt_data          ));*/
									
cpt_cpu_r_ctrl U_cpt_cpu_r_ctrl(
	.clk         (clk                 ) ,
	.rst_n       (rst_n               ) ,
    .ram_2p_cfg_register(ram_2p_cfg_register),
	
	.dpram0_wren  (cpt_dpram_wren     ) ,           
	.dpram0_waddr (cpt_dpram_addr[8:0]) ,   
	.dpram0_wdata (cpt_dpram_data     ) ,   
	.dpram0_rden  (cpu_rdcpt_en       ) ,           
	.dpram0_raddr (cpu_rdcpt_addr     ) ,   
	.dpram0_rdata (cpu_rdcpt_data     )
	
    );

cpt_state_fifo #(.PTR(CPT_NUM_WIDTH),.WORDS({1'b1,{(CPT_NUM_WIDTH){1'b0}}}),.W_SIZE(32),.A_FULL({(CPT_NUM_WIDTH){1'b1}})) 
u_cpt_state_fifo (

      .clock(clk)                         ,
      .rst_n(rst_n)                       ,
      .ram_2p_cfg_register(ram_2p_cfg_register),

      .fifo_wen(cpt_info_fifo_wren)       ,
      .fifo_wdata(cpt_info_fifo_data)     ,
      .fifo_ren(cpt_info_fifo_ren)        ,

      .fifo_rdata (cpt_info_fifo_rdata)   ,
      .fifo_empty_rd(cpt_info_fifo_empty) ,
      .fifo_cnt_wr (cpt_info_fifo_num)    ,
      .almost_full (cpt_info_fifo_full)
      );  


always @(posedge clk or negedge rst_n)
if(!rst_n)
      cpt_info_fifo_ren_ff <= 1'b0;
else 
      cpt_info_fifo_ren_ff <= cpt_info_fifo_ren;

always @(posedge clk or negedge rst_n)
if(!rst_n)
      cpt_info_fifo_rdata_reg <= 32'd0;
else if(cpt_info_fifo_ren_ff)
      cpt_info_fifo_rdata_reg <= cpt_info_fifo_rdata;
else
      cpt_info_fifo_rdata_reg <= cpt_info_fifo_rdata_reg;

assign cpt_info_fifo_rdata_d1 = (cpt_info_fifo_ren_ff == 1'b1)? cpt_info_fifo_rdata : cpt_info_fifo_rdata_reg;

/*
always @(posedge clk or negedge rst_n)
if(!rst_n)
      cpt_info_fifo_num_reg <= 9'd0;
else 
      cpt_info_fifo_num_reg <= cpt_info_fifo_num;
*/

assign cpt_fifo_status ={1'b0, cpt_start_en , cpt_info_fifo_rdata_d1[26:16], cpt_info_fifo_rdata_d1[9:0] ,cpt_info_fifo_num};     //[29:19]frame_len , [18:9]strat_adder , [8:0]??????
      
endmodule		  




			 
			 
			 
			 
			 
			 
			 
			 
			 
			 
